import com.alibaba.fastjson.JSONObject;
import com.mongodb.*;
import com.mongodb.MongoClient;
import com.mongodb.client.*;
import com.mongodb.client.model.Filters;
import com.mongodb.client.model.Sorts;
import org.bson.Document;
import org.bson.conversions.Bson;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Pattern;

import static com.mongodb.client.model.Accumulators.sum;
import static com.mongodb.client.model.Aggregates.group;
import static com.mongodb.client.model.Aggregates.match;
import static com.mongodb.client.model.Filters.eq;

public class MongoDbDriver {

    public void testConnect() {
        MongoClient mongoClient = new MongoClient("localhost", 27017);
        MongoDatabase database = mongoClient.getDatabase("xingxing");

        mongoClient.close();
    }

    public void testConnectByUser() {
        //--1 参数
        // mongodb://[username:password@]host1[:port1][,...hostN[:portN]]][/[database][?options]]

        //--2 独立MongoDB
        // mongodb://mongodb0.example.com:27017/admin

        //--3 如果开启了访问控制
        // 如果用户名或密码包含at符号@，冒号：，斜杠/或百分号％字符，请使用百分比编码方式消除歧义
        // mongodb://myDBReader:D1fficultP%40ssw0rd@mongodb0.example.com:27017/admin

        //--4 对于副本集群
        // mongodb://mongodb0.example.com:27017,mongodb1.example.com:27017,mongodb2.example.com:27017/admin?replicaSet=myRepl

        //--5 如果开启了访问控制，请包括用户凭据
        // mongodb://myDBReader:D1fficultP%40ssw0rd@mongodb0.example.com:27017,mongodb1.example.com:27017,mongodb2.example.com:27017/admin?replicaSet=myRepl

        String uri = "mongodb://localhost:27017";
        MongoClient mongoClient = new MongoClient(new MongoClientURI(uri));
        MongoDatabase database = mongoClient.getDatabase("lesson");
        MongoCollection<Document> lesson = database.getCollection("lesson");


    }

//    public void testConnectByPass() {
//        List<ServerAddress> adds = new ArrayList<>();
//        ServerAddress serverAddress = new ServerAddress("localhost", 27017);
//        adds.add(serverAddress);
//
//        List<MongoCredential> credentials = new ArrayList<>();
//        MongoCredential mongoCredential = MongoCredential.createScramSha1Credential("username", "databaseName", "password".toCharArray());
//        credentials.add(mongoCredential);
//
//        MongoClient mongoClient = new MongoClient(adds, credentials);
//    }

    public void testAdd() {
        //--1
        String uri = "mongodb://localhost:27017";
        MongoClient mongoClient = new MongoClient(new MongoClientURI(uri));
        MongoDatabase database = mongoClient.getDatabase("xingxing");

        //--2
        MongoCollection<Document> tableDoc = database.getCollection("tableDoc");
        tableDoc.drop();

        //--3
        Document doc1 = new Document("title", "good day")
                .append("owner", "tom")
                .append("words", 300)
                .append("comments", Arrays.asList(
                        new Document("author", "joe").append("score", 3).append("comment", "good"),
                        new Document("author", "white").append("score", 1).append("comment", "oh no")));

        Document doc2 = new Document("title", "good")
                .append("owner", "john")
                .append("words", 400)
                .append("comments", Arrays.asList(
                        new Document("author", "william").append("score", 4).append("comment", "good"),
                        new Document("author", "white").append("score", 6).append("comment", "very good")));

        Document doc3 = new Document("title", "good night")
                .append("owner", "mike")
                .append("words", 200)
                .append("tag", Arrays.asList(1, 2, 3, 4));

        Document doc4 = new Document("title", "happiness")
                .append("owner", "tom")
                .append("words", 1480)
                .append("tag", Arrays.asList(2, 3, 4));

        Document doc5 = new Document("title", "a good thing")
                .append("owner", "tom")
                .append("words", 180)
                .append("tag", Arrays.asList(1, 2, 3, 4, 5));

        tableDoc.insertMany(Arrays.asList(doc1, doc2, doc3, doc4, doc5));
    }

    public void testFind1() {
        //--1
        String uri = "mongodb://localhost:27017";
        MongoClient mongoClient = new MongoClient(new MongoClientURI(uri));
        MongoDatabase database = mongoClient.getDatabase("xingxing");

        //--2
        MongoCollection<Document> tableDoc = database.getCollection("tableDoc");

        //--3
        AggregateIterable<Document> iterable = tableDoc.aggregate(
                Arrays.asList(
                        match(eq("owner", "tom")),
                        group("$author", sum("totalWords", "$words"))));
        MongoCursor<Document> it = iterable.iterator();
        while (it.hasNext()){
            Document document1 = it.next();
            System.out.println(document1.toJson());
        }
    }

    public void testFind2() {
        //--1
        String uri = "mongodb://localhost:27017";
        MongoClient mongoClient = new MongoClient(new MongoClientURI(uri));
        MongoDatabase database = mongoClient.getDatabase("xingxing");

        //--2
        MongoCollection<Document> tableDoc = database.getCollection("tableDoc");

        //--3
        //加入查询条件
        BasicDBObject query = new BasicDBObject();
        //时间区间查询 记住如果想根据这种形式进行时间的区间查询 ，存储的时候 记得把字段存成字符串，就按yyyy-MM-dd HH:mm:ss 格式来
        query.put("times", new BasicDBObject("$gte", "2018-06-02 12:20:00").append("$lte","2018-07-04 10:02:46"));
        //模糊查询
        Pattern pattern = Pattern.compile("^.*王.*$", Pattern.CASE_INSENSITIVE);
        query.put("userName", pattern);
        //精确查询
        query.put("id", "11");

        //skip 是分页查询，从第0条开始查10条数据。 Sorts是排序用的。有descending 和ascending
        MongoCursor<Document> cursor = tableDoc.find(query).sort(Sorts.orderBy(Sorts.descending("times"))).skip(0).limit(10).iterator();//
        int unm=0;
        try {
            while (cursor.hasNext()) {
//                UserBehaviorLogs userBehaviorLogs = new UserBehaviorLogs();
                //查询出的结果转换成jsonObject,然后进行封装或者直接返回给前端处理。我这是封装成对象了
                JSONObject jsonObject = JSONObject.parseObject( cursor.next().toJson().toString());
//                userBehaviorLogs.setId(jsonObject.getString("id"));//id
//                userBehaviorLogs.setUserId(jsonObject.getString("userId"));//用户id
//                userBehaviorLogs.setUserName(jsonObject.getString("userName"));//用户名称
//                userBehaviorLogs.setParams(jsonObject.getString("params"));//参数
//                userBehaviorLogs.setException(jsonObject.getString("Exception"));//异常信息
//                userBehaviorLogs.setTimes(jsonObject.getString("times")+"");//创建时间
                unm++;
//                System.out.println(unm+"="+userBehaviorLogs.getTimes()+"==="+userBehaviorLogs.getId());
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            cursor.close();
        }
    }

    public void testUpdate() {
        MongoClient mongoClient = new MongoClient("localhost", 27017);
        MongoDatabase mongoDatabase = mongoClient.getDatabase("demo_db_name");
        MongoCollection<Document> collection = mongoDatabase.getCollection("demo_collcetion_name");

        //-- add
        Document document = new Document("name","王某某")
                .append("gender", "男")
                .append("age", 10);
        collection.insertOne(document);

        //-- add many
        List<Document> list = new ArrayList<>();
        for(int i = 0;  i < 5;  i++){
            list.add( new Document("number", i).append("name","王某某"));
        }
        collection.insertMany(list);

        //-- delete
        Bson filter = Filters.eq("age",3);
        collection.deleteOne(filter);

        //-- delete many
        Bson filter1 = Filters.eq("age",3);
        collection.deleteMany(filter1);

        //-- update
        //筛选条件
        Bson filter2 = Filters.eq("name", "王某某");
        //需改内容
        Document document2 = new Document("$set", new Document("age", 100));
        //执行修改
        collection.updateOne(filter2, document2);

        //-- update many
        //筛选条件
        Bson filter3 = Filters.eq("name", "王某某");
        //需改内容
        Document document3 = new Document("$set", new Document("age", 100));
        //执行修改
        collection.updateMany(filter3, document3);

        //-- find 查找集合中的所有文档
        FindIterable findIterable = collection.find();
        MongoCursor cursor = findIterable.iterator();
        while (cursor.hasNext()) {
            System.out.println(cursor.next());
        }

        //-- find 查找集合中的指定文档
        Bson filter4 = Filters.eq("age", 1);
        FindIterable findIterable4 = collection.find(filter);
        MongoCursor cursor4 = findIterable.iterator();
        while (cursor.hasNext()) {
            System.out.println(cursor.next());
        }

        //-- find 查找集合中的指定文档中的第一个文档
        FindIterable findIterable5 = collection.find();
        Document document5 = (Document) findIterable.first();
        System.out.println(document5);

        //--
        //collection.deleteOne();
        //collection.deleteMany();



    }

    // https://blog.csdn.net/autfish/article/details/51379379
    public static void main(String[] args) {

        MongoDbDriver mongoDbDriver = new MongoDbDriver();
        mongoDbDriver.testConnect();
        //mongoDbDriver.testConnectByUser();
        //mongoDbDriver.testAdd();
        mongoDbDriver.testFind1();
    }


}
